﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

namespace SEO.Spider
{
    /// <summary>
    /// 版权所有: 版权所有(C) 2011，Adin Lee
    /// 内容摘要: 百度搜索结果抓取
    /// 完成日期：2011年6月1日
    /// 版    本：V1.0 
    /// 作    者：Adin
    /// </summary>
    public class BaiduResult
    {
        /// <summary>
        /// 抓取百度搜索结果
        /// </summary>
        /// <param name="strWebUrl">网址</param>
        /// <param name="strStartMarkString">开始标记</param>
        /// <param name="strEndMarkString">结束标记</param>
        /// <param name="rb">显示实时消息控件</param>
        /// <param name="strSourceName">关键词</param>
        public void AccordingURLGetResultList(string strWebUrl, string strStartMarkString, string strEndMarkString, System.Windows.Forms.RichTextBox rb, string strKeywordsName)
        {
            try
            {
                SEO.Utility.WebClient wc = new SEO.Utility.WebClient();
                wc.Encoding = System.Text.Encoding.GetEncoding("gb2312");
                wc.OpenRead(strWebUrl);
                string GetHtmlCode = wc.RespHtml;

                //匹配列表源代码
                Regex rx = new Regex(strStartMarkString + "(?<content>[\\s\\S]*)?" + strEndMarkString, RegexOptions.Singleline);
                string strGetListHtmlContent = rx.Match(GetHtmlCode).Result("${content}");

                GetSearchResultsByLinks(strGetListHtmlContent, rb, strKeywordsName);
            }
            catch (Exception ex)
            {
                string strError = "百度搜索结果列表抓取匹配失败，关键词：" + strKeywordsName + "\r\n" + ex.Message;
                SEO.Utility.Log.SaveErrorLog("抓取百度搜索结果入口 -> " + strError);
            }

        }

        /// <summary>
        /// 根据网址获取搜索结果列表数据
        /// </summary>
        /// <param name="strGetHtmlContent">匹配到的HTML代码</param>
        /// <param name="rb">显示实时消息控件</param>
        /// <param name="strKeywordsName">关键词</param>
        public void GetSearchResultsByLinks(string strGetHtmlContent, System.Windows.Forms.RichTextBox rb, string strKeywordsName)
        {
            int iRankNum = 0;
            try
            {
                Regex clearString = new Regex("<span class=\"g\">(.+?)</span>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
                Match m = null;
                for (m = clearString.Match(strGetHtmlContent); m.Success; m = m.NextMatch())
                {
                    iRankNum++;

                    //匹配百度左侧排名、对应网址、快照日期
                    //<span class="g">www.czzww.com/a/xieren/20110123/70941.html 2011-4-23  </span>
                    string strWebsiteUrl = m.Groups[1].ToString().Trim();
                    strWebsiteUrl = strWebsiteUrl.Replace(" ", "|");
                    string[] splitValue = strWebsiteUrl.Split(new char[] { '|' });
                    strWebsiteUrl = splitValue[0].ToString().Trim();
                    strWebsiteUrl = SEO.Utility.StringHelper.CleanHtml(strWebsiteUrl);
                    string strCachedDate = splitValue[1].ToString().Trim();

                    SEO.Utility.PublicValue.SaveMessage(Convert.ToDateTime(DateTime.Now).ToString("MM-dd HH:mm:ss") + " 正在抓取关键词【" + strKeywordsName + "】百度左侧排名数据...");
                    rb.Text = SEO.Utility.PublicValue.GetMessage();

                    string strStatus = "";
                    try
                    {
                        SEO.DAL.KeywordsRankDAL krdal = new DAL.KeywordsRankDAL();
                        SEO.Model.KeywordsRank kr = new Model.KeywordsRank();
                        kr.RankID = krdal.GetAutoAddNum();
                        kr.KeyName = strKeywordsName;
                        kr.RankNum = iRankNum;
                        kr.WebUrl = strWebsiteUrl;
                        kr.CachedDate = strCachedDate;
                        kr.SEType = "百度";
                        //添加
                        SEO.BLL.KeywordsRankBLL krbll = new BLL.KeywordsRankBLL();
                        krbll.InsertKeywordsRankBLL(kr);

                        strStatus = "成功！第" + iRankNum + "名，网址：" + strWebsiteUrl;
                    }
                    catch (Exception ex)
                    {
                        strStatus = "失败！";
                        SEO.Utility.Log.SaveErrorLog("添加KeywordsRank数据到本地Sqlite数据库 -> " + ex.Message);
                    }

                    SEO.Utility.PublicValue.SaveMessage("\r\n" + Convert.ToDateTime(DateTime.Now).ToString("mm:ss") + " 状态：" + strStatus);
                    rb.Text = SEO.Utility.PublicValue.GetMessage();
                }
            }
            catch (Exception ex)
            {
                SEO.Utility.Log.SaveErrorLog("获取网页地址列表 ->" + ex.Message);
            }
        }


        /// <summary>
        /// 抓取百度搜索结果:用于行业数据分析，保存自定义格式文件中
        /// </summary>
        /// <param name="strWebUrl">网址</param>
        /// <param name="strStartMarkString">开始标记</param>
        /// <param name="strEndMarkString">结束标记</param>
        /// <param name="rb">显示实时消息控件</param>
        /// <param name="strSourceName">关键词</param>
        public void AccordingURLGetSearchResults(string strWebUrl, string strStartMarkString, string strEndMarkString, System.Windows.Forms.RichTextBox rb, string strKeywordsName, string strFilePath)
        {
            try
            {
                SEO.Utility.WebClient wc = new SEO.Utility.WebClient();
                wc.Encoding = System.Text.Encoding.GetEncoding("gb2312");
                wc.OpenRead(strWebUrl);
                string GetHtmlCode = wc.RespHtml;

                //匹配列表源代码
                Regex rx = new Regex(strStartMarkString + "(?<content>[\\s\\S]*)?" + strEndMarkString, RegexOptions.Singleline);
                string strGetListHtmlContent = rx.Match(GetHtmlCode).Result("${content}");

                GetSearchResultsByLinksForIndustry(strGetListHtmlContent, rb, strKeywordsName, strFilePath);
            }
            catch (Exception ex)
            {
                string strError = "百度搜索结果列表抓取匹配失败，关键词：" + strKeywordsName + "\r\n" + ex.Message;
                SEO.Utility.Log.SaveErrorLog("抓取百度搜索结果入口 -> " + strError);
            }

        }

        /// <summary>
        /// 根据网址获取搜索结果列表数据:用于行业主分类数据分析，保存自定义格式文件中
        /// </summary>
        /// <param name="strGetHtmlContent">匹配到的HTML代码</param>
        /// <param name="rb">显示实时消息控件</param>
        /// <param name="strKeywordsName">关键词</param>
        public void GetSearchResultsByLinksForIndustry(string strGetHtmlContent, System.Windows.Forms.RichTextBox rb, string strKeywordsName,string strFilePath)
        {
            int iRankNum = 0;
            try
            {
                Regex clearString = new Regex("<span class=\"g\">(.+?)</span>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
                Match m = null;
                for (m = clearString.Match(strGetHtmlContent); m.Success; m = m.NextMatch())
                {
                    iRankNum++;

                    //匹配百度左侧排名、对应网址、快照日期
                    //<span class="g">www.czzww.com/a/xieren/20110123/70941.html 2011-4-23  </span>
                    //<span class="g">www.b2b.cn/special/ShangHaiMoJuGang/gongs  2011-5-26  </span>
                    string strWebsiteUrl = m.Groups[1].ToString().Trim();
                    if (strWebsiteUrl.Contains("..."))
                    {
                        strWebsiteUrl = strWebsiteUrl.Replace("...", "");
                        strWebsiteUrl = strWebsiteUrl.Replace("  ", " ");
                    }
                    strWebsiteUrl = strWebsiteUrl.Replace(" ", "|");
                    string[] splitValue = strWebsiteUrl.Split(new char[] { '|' });
                    strWebsiteUrl = splitValue[0].ToString().Trim();
                    strWebsiteUrl = SEO.Utility.StringHelper.CleanHtml(strWebsiteUrl);
                    string strCachedDate = splitValue[1].ToString().Trim();

                    SEO.Utility.PublicValue.SaveMessage(Convert.ToDateTime(DateTime.Now).ToString("MM-dd HH:mm:ss") + " 正在生成关键词【" + strKeywordsName + "】百度左侧排名数据...");
                    rb.Text = SEO.Utility.PublicValue.GetMessage();

                    //关键词，排名，网址，快照日期，抓取日期
                    //string strValue = strKeywordsName + "," + iRankNum + "," + strWebsiteUrl + "," + strCachedDate + "," + DateTime.Now.ToString("yyyy-MM-dd");
                    //strGetTop10Cotnent += strValue + ";";

                    string strStatus = "";
                    try
                    {
                        SEO.DAL.KeywordsRankDAL krdal = new DAL.KeywordsRankDAL();
                        SEO.Model.KeywordsRank kr = new Model.KeywordsRank();
                        kr.RankID = krdal.GetAutoAddNum();
                        kr.KeyName = strKeywordsName;
                        kr.RankNum = iRankNum;
                        kr.WebUrl = strWebsiteUrl;
                        kr.CachedDate = strCachedDate;
                        kr.SEType = "百度";
                        kr.IndustryID = int.Parse(strFilePath);
                        //添加
                        SEO.BLL.KeywordsRankBLL krbll = new BLL.KeywordsRankBLL();
                        krbll.InsertKeywordsRankBLL(kr);

                        strStatus = "成功！第" + iRankNum + "名，网址：" + strWebsiteUrl;
                    }
                    catch (Exception ex)
                    {
                        strStatus = "失败！";
                        SEO.Utility.Log.SaveErrorLog("添加KeywordsRank数据到本地Sqlite数据库 -> " + ex.Message);
                    }

                    SEO.Utility.PublicValue.SaveMessage("\r\n" + Convert.ToDateTime(DateTime.Now).ToString("mm:ss") + " 状态：成功");
                    rb.Text = SEO.Utility.PublicValue.GetMessage();
                }
            }
            catch (Exception ex)
            {
                SEO.Utility.Log.SaveErrorLog("获取网页地址列表 ->" + ex.Message);
            }
        }

        /// <summary>
        /// 根据主行业获取搜索结果列表数据:用于行业主分类数据分析，保存自定义格式文件中
        /// </summary>
        /// <param name="strGetHtmlContent">匹配到的HTML代码</param>
        /// <param name="rb">显示实时消息控件</param>
        /// <param name="strKeywordsName">关键词</param>
        public void GetSearchResultsByParentIDForIndustry(string strGetHtmlContent, System.Windows.Forms.RichTextBox rb, string strKeywordsName, string strFilePath)
        {
            int iRankNum = 0;
            try
            {
                string strGetTop10Cotnent = "";

                Regex clearString = new Regex("<span class=\"g\">(.+?)</span>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
                Match m = null;
                for (m = clearString.Match(strGetHtmlContent); m.Success; m = m.NextMatch())
                {
                    iRankNum++;

                    //匹配百度左侧排名、对应网址、快照日期
                    //<span class="g">www.czzww.com/a/xieren/20110123/70941.html 2011-4-23  </span>
                    string strWebsiteUrl = m.Groups[1].ToString().Trim();
                    strWebsiteUrl = strWebsiteUrl.Replace(" ", "|");
                    string[] splitValue = strWebsiteUrl.Split(new char[] { '|' });
                    strWebsiteUrl = splitValue[0].ToString().Trim();
                    strWebsiteUrl = SEO.Utility.StringHelper.CleanHtml(strWebsiteUrl);
                    string strCachedDate = splitValue[1].ToString().Trim();

                    SEO.Utility.PublicValue.SaveMessage(Convert.ToDateTime(DateTime.Now).ToString("MM-dd HH:mm:ss") + " 正在生成关键词【" + strKeywordsName + "】百度左侧排名数据...");
                    rb.Text = SEO.Utility.PublicValue.GetMessage();

                    //关键词，排名，网址，快照日期，抓取日期
                    string strValue = strKeywordsName + "," + iRankNum + "," + strWebsiteUrl + "," + strCachedDate + "," + DateTime.Now.ToString("yyyy-MM-dd");
                    strGetTop10Cotnent += strValue + ";";

                    SEO.Utility.PublicValue.SaveMessage("\r\n" + Convert.ToDateTime(DateTime.Now).ToString("mm:ss") + " 状态：成功");
                    rb.Text = SEO.Utility.PublicValue.GetMessage();
                }

                //每天数据分隔符"@"
                strGetTop10Cotnent = strGetTop10Cotnent.Substring(0, strGetTop10Cotnent.Length - 1) + "@";

                try
                {
                    //存储
                    string strPassword = "adin-seo!@#53344521";
                    string strTxtFile = strFilePath + ".txt";
                    SEO.Utility.Log.SaveIndustryInfo(strGetTop10Cotnent, strFilePath);
                    string strEncryptedFile = strFilePath + ".seo";
                    SEO.Utility.CryptoHelper.EncryptFile(strTxtFile, strEncryptedFile, strPassword);
                    //删除txt文件
                    //File.Delete(strTxtFile);
                }
                catch (Exception ex)
                {
                    SEO.Utility.Log.SaveErrorLog("存储搜索结果数据岛加密自定义文件 ->" + ex.Message);
                }
            }
            catch (Exception ex)
            {
                SEO.Utility.Log.SaveErrorLog("获取网页地址列表 ->" + ex.Message);
            }
        }



        /// <summary>
        /// 抓取百度搜索结果:用于行业数据分析，保存自定义格式文件中
        /// </summary>
        /// <param name="strWebUrl">网址</param>
        /// <param name="strStartMarkString">开始标记</param>
        /// <param name="strEndMarkString">结束标记</param>
        /// <param name="rb">显示实时消息控件</param>
        /// <param name="strSourceName">关键词</param>
        public void AccordingURLGetSearchResultsForDay(string strWebUrl, string strStartMarkString, string strEndMarkString, System.Windows.Forms.RichTextBox rb, string strKeywordsName, string strFilePath)
        {
            try
            {
                SEO.Utility.WebClient wc = new SEO.Utility.WebClient();
                wc.Encoding = System.Text.Encoding.GetEncoding("gb2312");
                wc.OpenRead(strWebUrl);
                string GetHtmlCode = wc.RespHtml;

                //匹配列表源代码
                Regex rx = new Regex(strStartMarkString + "(?<content>[\\s\\S]*)?" + strEndMarkString, RegexOptions.Singleline);
                string strGetListHtmlContent = rx.Match(GetHtmlCode).Result("${content}");

                GetSearchResultsByLinksForDay(strGetListHtmlContent, rb, strKeywordsName, strFilePath);
            }
            catch (Exception ex)
            {
                string strError = "百度搜索结果列表抓取匹配失败，关键词：" + strKeywordsName + "\r\n" + ex.Message;
                SEO.Utility.Log.SaveErrorLog("抓取百度搜索结果入口 -> " + strError);
            }

        }

        /// <summary>
        /// 根据网址获取搜索结果列表数据:用于行业主分类数据分析，保存自定义格式文件中
        /// </summary>
        /// <param name="strGetHtmlContent">匹配到的HTML代码</param>
        /// <param name="rb">显示实时消息控件</param>
        /// <param name="strKeywordsName">关键词</param>
        public void GetSearchResultsByLinksForDay(string strGetHtmlContent, System.Windows.Forms.RichTextBox rb, string strKeywordsName, string strFilePath)
        {
            int iRankNum = 0;
            try
            {
                Regex clearString = new Regex("<span class=\"g\">(.+?)</span>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
                Match m = null;
                for (m = clearString.Match(strGetHtmlContent); m.Success; m = m.NextMatch())
                {
                    iRankNum++;

                    //匹配百度左侧排名、对应网址、快照日期
                    //<span class="g">www.czzww.com/a/xieren/20110123/70941.html 2011-4-23  </span>
                    //<span class="g">www.b2b.cn/special/ShangHaiMoJuGang/gongs  2011-5-26  </span>
                    string strWebsiteUrl = m.Groups[1].ToString().Trim();
                    if (strWebsiteUrl.Contains("..."))
                    {
                        strWebsiteUrl = strWebsiteUrl.Replace("...", "");
                        strWebsiteUrl = strWebsiteUrl.Replace("  ", " ");
                    }
                    strWebsiteUrl = strWebsiteUrl.Replace(" ", "|");
                    string[] splitValue = strWebsiteUrl.Split(new char[] { '|' });
                    strWebsiteUrl = splitValue[0].ToString().Trim();
                    strWebsiteUrl = SEO.Utility.StringHelper.CleanHtml(strWebsiteUrl);
                    string strCachedDate = splitValue[1].ToString().Trim();

                    SEO.Utility.PublicValue.SaveMessage(Convert.ToDateTime(DateTime.Now).ToString("MM-dd HH:mm:ss") + " 正在生成关键词【" + strKeywordsName + "】百度左侧排名数据...");
                    rb.Text = SEO.Utility.PublicValue.GetMessage();

                    //关键词，排名，网址，快照日期，抓取日期
                    //string strValue = strKeywordsName + "," + iRankNum + "," + strWebsiteUrl + "," + strCachedDate + "," + DateTime.Now.ToString("yyyy-MM-dd");
                    //strGetTop10Cotnent += strValue + ";";

                    string strStatus = "";
                    try
                    {
                        //添加左侧排名网站
                        SEO.DAL.KeywordsDayDAL kddal = new DAL.KeywordsDayDAL();
                        SEO.Model.KeywordsDay kd = new Model.KeywordsDay();
                        int iDayID = kddal.GetAutoAddNum();
                        kd.DayID = iDayID; 
                        kd.KeyName = strKeywordsName;
                        kd.WebUrl = strWebsiteUrl;
                        kd.CachedDate = strCachedDate;
                        SEO.BLL.KeywordsDayBLL kdbll = new BLL.KeywordsDayBLL();
                        kdbll.InsertKeywordsDayBLL(kd);

                        //添加左侧排名名次
                        SEO.DAL.KeywordsDayRankRankDAL kdrdal = new DAL.KeywordsDayRankRankDAL();
                        SEO.Model.KeywordsDayRank kdr = new Model.KeywordsDayRank();
                        int iRankID = kdrdal.GetAutoAddNum();
                        kdr.RankID = iRankID;
                        kdr.RankNum = iRankNum;
                        kdr.DayID = iDayID;
                        SEO.BLL.KeywordsDayRankBLL kdrbll = new BLL.KeywordsDayRankBLL();
                        kdrbll.InsertKeywordsDayRankBLL(kdr);

                        strStatus = "成功！第" + iRankNum + "名，网址：" + strWebsiteUrl;
                    }
                    catch (Exception ex)
                    {
                        strStatus = "失败！";
                        SEO.Utility.Log.SaveErrorLog("添加KeywordsRank数据到本地Sqlite数据库 -> " + ex.Message);
                    }

                    SEO.Utility.PublicValue.SaveMessage("\r\n" + Convert.ToDateTime(DateTime.Now).ToString("mm:ss") + " 状态：" + strStatus);
                    rb.Text = SEO.Utility.PublicValue.GetMessage();
                }
            }
            catch (Exception ex)
            {
                SEO.Utility.Log.SaveErrorLog("获取网页地址列表 ->" + ex.Message);
            }
        }
    }
}
